package com.example.exceldemo.service.impl;

import cn.afterturn.easypoi.entity.ImageEntity;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import com.alibaba.excel.EasyExcel;
import com.example.exceldemo.config.WordUtil;
import com.example.exceldemo.entity.*;
import com.example.exceldemo.enuns.FileType;
import com.example.exceldemo.exception.ServiceException;
import com.example.exceldemo.service.EasyPoiService;
import com.example.exceldemo.utils.EasyPoiUtils;
import com.example.exceldemo.utils.FileUtils;
import com.example.exceldemo.utils.PdfUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;


/**
 * @Description
 * @Author xiaohuang
 * @Date 2024/9/10
 */
@Slf4j
@Service
public class EasyPoiServiceImpl implements EasyPoiService {
    private static final String CHARSET_UTF8 = "utf-8";
    private static final String EXCEL_TEMPLATE = "template/fillexecl/person.xlsx";
    private static final String EXCEL_SHEET_TEMPLATE = "template/fillexecl/person2.xlsx";

    @Autowired
    private WordUtil wordUtil;

    @Override
    public void autowiredExp() {
        EasyPoiUtils.export(null, "sheet1", User.class, testGetTestData(), "注解导出列表", false, true);
    }

    @Override
    public void autowiredObjExp() {
        EasyPoiUtils.export("注解用户列表对象标题", "sheet1", UserEntity.class, getUserEntity(), "注解用户列表对象", false, true);

    }

    @Override
    public void autowiredListExp() {
        EasyPoiUtils.export("用户列表导出一对多合并单元格", "sheet1", UserEntityList.class, getUserEntityList(), "注解用户列表导出一对多合并单元格", true, true);
    }

    @Override
    public void autowiredImageExp() {
        EasyPoiUtils.export("用户列表导出加图片", "sheet1", UserImageEntity.class, getUserImage(), "注解用户列表导出加图片", false, true);
    }

    @Override
    public void autowiredBigExp() {
        if (getBigUser().size() >= 10000)
            EasyPoiUtils.manySheetExport("数据超过100000，页数100000导致多建sheet0为空", "sheet0", User.class, getBigUser(), "用户列表导出大量数据", 100000);
        else
            EasyPoiUtils.export("用户列表导出大量数据", "sheet1", User.class, getBigUser(), "用户列表导出大量数据", false, true);
    }

    @Override
    public void bigExp() {
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        //模拟分页获取数据
        if (getBigUser().size() >= 100000)
            EasyPoiUtils.manySheetExport("数据超过100000，页数<100000导出正常", "sheet0", User.class, getBigUser(), "用户列表导出大量数据", 99999);
        else
            EasyPoiUtils.export("用户列表导出大量数据", "" +
                    "" +
                    "", User.class, getBigUser(), "用户列表导出大量数据", false, true);
    }

    @Override
    public void importPoi(MultipartFile file) {
        try {
            EasyPoiUtils.importExcel(file.getInputStream(), User.class);
        } catch (IOException e) {
            throw new ServiceException("导入数据时发生错误:", e);

        }

    }


    @Override
    public void excelExportTemplate() {
        String realImagePath = "E:/data/file/faceimg/tmp/1.jpg";
        //存放单个数据
        HashMap<String, Object> mapHead = new HashMap<>();
        mapHead.put("title", "easyPoi模板导出");
        mapHead.put("date", LocalDate.now().toString());
        mapHead.put("test", "测试表格尾");
        // 具体来说，ImageEntity是一个Java类，用于表示一个图像实体，其中包含了图像的各种属性和数据。
        ImageEntity simage = new ImageEntity();
        simage.setHeight(80);
        simage.setWidth(80);
        //将simage对象的类型设置为byte[]类型。
        simage.setType(ImageEntity.Data);
        simage.setData(FileUtils.getByte(realImagePath)); //字节流读取
        List<Map<String, Object>> works = new ArrayList<>();
        //存放表格数据
        for (int i = 0; i < 4; i++) {
            Map<String, Object> work = new HashMap<>();
            work.put("num", (i + 1) + "");
            work.put("workNo", i + ".no");
            work.put("remark", "能吃22222222222222222222222222222222222222222222222222222");
            work.put("time", "2024-12-31");
            work.put("image", simage);
            works.add(work);
        }
        mapHead.put("works", works);
        try {
            wordUtil.exportExcel(EXCEL_TEMPLATE, "easyPoi模板导出excel", mapHead, FileType.XLS, "person.xlsx", null);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void excelExportTemplates() {
        String realImagePath = "E:/data/file/faceimg/tmp/1.jpg";
        //sheet1数据
        HashMap<String, Object> mapHead = new HashMap<>();
        mapHead.put("title", "easyPoi多个模板导出excel");
        mapHead.put("date", LocalDate.now().toString());
        mapHead.put("test", "测试表格尾");
        // 具体来说，ImageEntity是一个Java类，用于表示一个图像实体，其中包含了图像的各种属性和数据。
        ImageEntity simage = new ImageEntity();
        simage.setHeight(80);
        simage.setWidth(80);
        //将simage对象的类型设置为byte[]类型。
        simage.setType(ImageEntity.Data);
        simage.setData(FileUtils.getByte(realImagePath)); //字节流读取
        List<Map<String, Object>> works = new ArrayList<>();
        //存放表格数据
        for (int i = 0; i < 4; i++) {
            Map<String, Object> work = new HashMap<>();
            work.put("num", (i + 1) + "");
            work.put("workNo", i + ".no");
            work.put("remark", "能吃22222222222222222222222222222222222222222222222222222");
            work.put("time", "2024-12-31");
            work.put("image", simage);
            works.add(work);
        }
        mapHead.put("works", works);
        //sheet2数据,不同sheet表单数据根据key区分
        mapHead.put("list", works);
        try {
            wordUtil.exportExcel(EXCEL_SHEET_TEMPLATE, "easyPoi多个模板导出excel", mapHead, FileType.XLS, "person2.xlsx", new String[]{"人员", "学生"});
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void initExcel() {
        List<ExcelExportEntity> colList = new ArrayList<>();
        //初始化表头字段属性
        ExcelExportEntity baseGroup = new ExcelExportEntity("", "base");
        List<ExcelExportEntity> baseList = new ArrayList<>();
        ExcelExportEntity name = new ExcelExportEntity("姓名", "name");
        name.setWidth(20);
        name.setOrderNum(1);
        ExcelExportEntity age = new ExcelExportEntity("年龄", "age");
        age.setWidth(10);
        age.setOrderNum(2);
        age.setType(10);
        ExcelExportEntity sex = new ExcelExportEntity("性别", "sex");
        sex.setWidth(10);
        sex.setOrderNum(3);
        sex.setType(10);
        sex.setReplace(new String[]{"男_1", "女_2"});
        ExcelExportEntity birthday = new ExcelExportEntity("生日", "birthday");
        birthday.setWidth(20);
        birthday.setOrderNum(4);
        birthday.setFormat("yyyy-MM-dd");
        ExcelExportEntity money = new ExcelExportEntity("存款", "money");
        money.setWidth(20);
        money.setOrderNum(5);
        money.setType(10);
        money.setFormat("yyyy-MM-dd");
        ExcelExportEntity rate = new ExcelExportEntity("及格率", "rate");
        rate.setWidth(20);
        rate.setOrderNum(6);
        rate.setType(10);
        rate.setSuffix("%");
        baseList.add(name);
        baseList.add(age);
        baseList.add(sex);
        baseList.add(birthday);
        baseList.add(money);
        baseList.add(rate);
        baseGroup.setList(baseList);
        colList.add(baseGroup);
        //封装数据
        List<Map<String, Object>> list = new ArrayList<>();
        List<User> userList = testGetTestData();
        if (!CollectionUtils.isEmpty(userList)){
            for (User user : userList) {
                Map<String, Object> dataMap = new HashMap<>();
                List<Map<String, Object>> baseDataList = new ArrayList<>();
                Map<String, Object> map = new HashMap<>();
                map.put("name", user.getName());
                map.put("age", user.getAge());
                map.put("sex", user.getSex());
                map.put("birthday", user.getBirthday());
                map.put("money", user.getMoney());
                map.put("rate", user.getRate());
                baseDataList.add(map);
                dataMap.put("base", baseDataList);
                list.add(dataMap);
            }
        }

        EasyPoiUtils.initExport("人员信息", "sheet0",  colList, list, "easypoi自定义导出人员信息", false,true);
    }


    public List<Map<String, Object>> getList() {
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> maps = new LinkedHashMap<>();
        maps.put("name", "李明");
        maps.put("sex", "男");
        maps.put("title1", "姓名1");
        maps.put("title2", "性别1");
        maps.put("field1", "t.name");
        maps.put("field2", "t.sex");
        list.add(maps);
        maps = new LinkedHashMap<>();
        maps.put("name", "小红");
        maps.put("sex", "女");
        maps.put("title1", "姓名2");
        maps.put("title2", "性别2");
        maps.put("field1", "t.name");
        maps.put("field2", "t.sex");
        list.add(maps);
        maps = new LinkedHashMap<>();
        maps.put("name", "小朵");
        maps.put("sex", "女");
        maps.put("title1", "姓名3");
        maps.put("title2", "性别3");
        maps.put("field1", "t.name");
        maps.put("field2", "t.sex");
        list.add(maps);
        return list;
    }

    public List<User> getBigUser() {
        List<User> users = new ArrayList<User>();
        for (int i = 0; i < 100000; i++) {
            User user = new User();
            user.setName("小凡" + i);
            user.setAge(i + 18);
            user.setSex(1);
            user.setBirthday(LocalDateTime.now());
            user.setRate(BigDecimal.valueOf(i));
            user.setMoney(BigDecimal.valueOf(i));
            users.add(user);
        }
        return users;
    }

    public List<UserImageEntity> getUserImage() {
        List<UserImageEntity> users = new ArrayList<UserImageEntity>();
        for (int i = 0; i < 5; i++) {
            UserImageEntity user = new UserImageEntity();
            user.setName("小凡" + i);
            user.setAge(i + 18);
            user.setSex(1);
            user.setBirthday(LocalDate.now());
            byte[] aByte = FileUtils.getByte("E:\\data\\file\\faceimg\\tmp\\1.jpg");
            user.setAvatar(aByte);
            users.add(user);
        }
        return users;
    }

    public List<User> testGetTestData() {
        List<User> users = new ArrayList<User>();
        for (int i = 0; i < 5; i++) {
            User user = new User();
            user.setName("小凡" + i);
            user.setAge(i + 18);
            user.setSex(1);
            user.setBirthday(LocalDateTime.now());
            user.setMoney(BigDecimal.valueOf(1000.01 + i));
            user.setRate(BigDecimal.valueOf(80.5 + i));
            users.add(user);
        }
        return users;
    }

    public List<UserEntity> getUserEntity() {
        List<UserEntity> users = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            UserEntity user = new UserEntity();
            user.setName("小凡" + i);
            user.setAge(i + 18);
            user.setSex("1");
            user.setBirthday(new Date());
            user.setUserBaseInfo(new UserBaseInfo("12121321" + i, "123456" + i));
            users.add(user);
        }
        return users;
    }

    public List<UserEntityList> getUserEntityList() {
        List<UserEntityList> users = new ArrayList<UserEntityList>();
        for (int i = 0; i < 5; i++) {
            UserEntityList user = new UserEntityList();
            user.setName("小凡" + i);
            user.setAge(i + 18);
            user.setSex("1");
            user.setBirthday(new Date());
            Product pro1 = new Product("冰箱" + i, 5000);
            Product pro2 = new Product("洗衣机" + i, 3000);
            Product pro3 = new Product("空调" + i, 4000);
            List<Product> products = Arrays.asList(pro1, pro2, pro3);
            user.setProducts(products);
            users.add(user);
        }
        return users;
    }
}
